package com.fingard.dsp.bank.directbank.citic01;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptData;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptDataHelper;
import com.fingard.dsp.bank.directConfig.ReceiptProConfig;
import com.fingard.dsp.bank.directbank.bankInterface.IReceiptPro;
import com.fingard.dsp.bank.reqrespobj.downloadreceipt.ReqQryReceipt;
import com.fingard.dsp.bank.reqrespobj.downloadreceipt.RetAtsReceipt;
import com.fingard.dsp.task.command.SyncReceipt;
import com.fingard.io.FileHelper;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.util.ZipHelper;
import com.fingard.util.secret.salary.FieldHiddenUtil;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;
import sun.misc.BASE64Decoder;

import java.io.File;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by aaron on 2020/4/29.
 */
public class CITIC01ReceiptPro extends CITIC01Base implements IReceiptPro {

    @Override
    public RetAtsReceipt qryReceiptOneDay(ReceiptProConfig pConfig, ReqQryReceipt pReqReceipt, Date pOneDay) throws Exception {

        //当1.1接口异常或1.1接口查询到最后一页时跳出循环
        String qryDay = Format.Date8Format.format(pOneDay);
        ReceiptDataHelper receiptHelper = null;//回单数据保存类，分区分表
        String aLog = "";
        try {
            receiptHelper = new ReceiptDataHelper(pReqReceipt.reqHeader.tenant, pOneDay);

            //查询回单信息
            qryReceiptInfo(receiptHelper, pReqReceipt, qryDay);

            //下载文件
            aLog = pReqReceipt.actNum + "," + qryDay + "回单数据查询完成，开始下载文件";
            WriteBankLogLn(aLog);
            FGBiz.logTrace.info(this.getLogCode(), aLog);

            ArrayList<ReceiptData> list = receiptHelper.getNeedDwnDataList(pReqReceipt.actNum, pOneDay);

            aLog = pReqReceipt.actNum + "," + qryDay + "需要进行下载的回单文件个数：" + list.size();
            WriteBankLogLn(aLog);
            FGBiz.logTrace.info(this.getLogCode(), aLog);

            if (list.size() <= 0) {
                return null;
            }
            //开始下载文件

            pdfDownLoad(receiptHelper, pConfig, pReqReceipt, list);

        } catch (Exception ex) {
            ex.printStackTrace();
            WriteBankLogLn(ex.getMessage());
            FGBiz.logTrace.error(this.getLogCode(), ex.getMessage());
        }finally {
            receiptHelper.close();
        }
        SyncReceipt.resetDelayCounter();//同步任务重新计数延时
        return null;
    }

    public void qryReceiptInfo(ReceiptDataHelper receiptHelper, ReqQryReceipt p_reqReceipt, String qryDateStr)throws Exception{
        String aLog ="";
        try{
            int startNo = 1;//页码数 默认查询第一页
            int tmpReadedCount = 0;//已读条数
            int tmpTotalCount =0;//总数

            do{
                //赋值通用参数
                CITIC01Header bankHeader = new CITIC01Header();
                bankHeader.action = "DLEDDRSQ";

                XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                //写入通用的头部节点
                writeCommonHeader(xmlWriter, bankHeader);
                String qryType ="";
                int cmpRe = DateHelper.compareDay(new Date(), Format.Date8Format.parse(qryDateStr));
                if (cmpRe == 0) {
                    qryType = "1";
                } else {
                    qryType = "2";//1：T+0 2：T+1
                }
                xmlWriter.writeElementString("qryType", qryType);//1：T+0 2：T+1
                xmlWriter.writeElementString("accNo", p_reqReceipt.actNum);
                if (StringHelper.isNullOrEmpty(p_reqReceipt.billType)||"null".equals(p_reqReceipt.billType)) {
                    xmlWriter.writeElementString("billType", "0");
                } else {
                    xmlWriter.writeElementString("billType", p_reqReceipt.billType);
                }
                xmlWriter.writeElementString("minAmt", "0.00");
                xmlWriter.writeElementString("maxAmt", "9999999999999.99");
                xmlWriter.writeElementString("startDate", qryDateStr);
                xmlWriter.writeElementString("endDate", qryDateStr);
                xmlWriter.writeElementString("pageSize", getBankConfig().getValueAsString("pageSize"));
                xmlWriter.writeElementString("startNo", startNo+"");

                xmlWriter.writeEndDocument();
                FGBiz.logTrace.info(this.getLogCode(), "发送银行的报文:"+xmlWriter.toXmlString());
                String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());
                FGBiz.logTrace.info(this.getLogCode(), "银行返回的报文:"+tmpStrRet[1]);
                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String tmpStatus = tmpBkReader.getFirstText("/stream/status");
                        String tmpStatusText = tmpBkReader.getFirstText("/stream/statusText");
                        if (tmpStatus != null && tmpStatus.equals("AAAAAAA")) {
                            if (tmpTotalCount!=-1) {
                                tmpTotalCount = Integer.parseInt(tmpBkReader.getFirstText("/stream/totalCount"));
                            }
                            while (tmpBkReader.read("/stream/list/row")){
                                tmpReadedCount++;
                                ReceiptData receiptData = new ReceiptData();
                                receiptData.bank = "302";
                                receiptData.srcSys = this.bankFront.bankCode;
                                receiptData.busRef = tmpBkReader.readedXElement.getSingleText("transeqNo");
                                receiptData.istNbr = tmpBkReader.readedXElement.getSingleText("brseqNo");//回单编号
                                receiptData.receiptNo =receiptData.istNbr;
                                receiptData.bnkSeqNo = tmpBkReader.readedXElement.getSingleText("transeqNo");//交易发起方流水号
                                String TRAN_DATE = tmpBkReader.readedXElement.getSingleText("tranDate");//交易日期
                                receiptData.busDate = Integer.parseInt(TRAN_DATE);
                                receiptData.ownAct = p_reqReceipt.actNum;
                                if (!qryDateStr.equals(TRAN_DATE)) {
                                    aLog = receiptData.receiptNo + "回单数据的日期" + TRAN_DATE + "与预期" + qryDateStr + "不符";
                                    WriteBankLogLn(aLog);
                                    FGBiz.logTrace.error(this.getLogCode(), aLog);
                                }
                                receiptData.amount = new BigDecimal(tmpBkReader.readedXElement.getSingleText("tranAmt"));//交易金额
                                String billType = tmpBkReader.readedXElement.getSingleText("billType");//票据类型
                                receiptData.receiptType = typeMapper(billType);
                                if("2".equals(qryType)){
//                                    <payerAccNo></payerAccNo><!--付款人账号（T+1返回） varchar(19)-->
                                    String payerAccNo = tmpBkReader.readedXElement.getSingleText("payerAccNo");
//                                    <payerAccNm></payerAccNm><!--付款人户名（T+1返回） varchar(122)-->
                                    String payerAccNm = tmpBkReader.readedXElement.getSingleText("payerAccNm");
//                                    <payeeAccNo></payeeAccNo><!--收款人账号（T+1返回） varchar(19)-->
                                    String payeeAccNo = tmpBkReader.readedXElement.getSingleText("payeeAccNo");
//                                    <payeeAccNm></payeeAccNm><!--收款人户名（T+1返回） varchar(122)-->
                                    String payeeAccNm = tmpBkReader.readedXElement.getSingleText("payeeAccNm");
                                    if(p_reqReceipt.actNum.equals(payerAccNo)){
                                        receiptData.oppActNum = payeeAccNo;
                                        receiptData.oppActName = payeeAccNm;
                                        receiptData.moneyWay = "1";
                                    }else  if(p_reqReceipt.actNum.equals(payeeAccNo)){
                                        receiptData.oppActNum =payerAccNo;
                                        receiptData.oppActName = payerAccNm;
                                        receiptData.moneyWay = "2";
                                    }
//                                    <cryType></cryType><!--币种（T+1返回）varchar(3)-->
                                    String cryType = tmpBkReader.readedXElement.getSingleText("cryType");
                                    receiptData.cur = convertCurToATS(cryType);
//                                    <bizType></bizType><!--业务类型（T+1返回）varchar(6)-->
                                }else {
//                            <otherRaccNo1></otherRaccNo1><!--对手方账号（T+0返回） varchar(19)-->
                                    receiptData.oppActNum = tmpBkReader.readedXElement.getSingleText("otherRaccNo1");
//                            <otherRaccNm1></otherRaccNm1><!--对手方账户名（T+0返回） varchar(122)-->
                                    receiptData.oppActName = tmpBkReader.readedXElement.getSingleText("otherRaccNm1");
//                            <cdfg></cdfg><!--借贷标识（T+0返回）varchar(1)， C：贷/收；D：借/付-->
                                    String cdfg = tmpBkReader.readedXElement.getSingleText("cdfg");
                                    if("C".equals(cdfg)){
                                        receiptData.moneyWay = "2";
                                    }else  if("D".equals(cdfg)){
                                        receiptData.moneyWay = "1";
                                    }
//                            <cryType1></cryType1><!--交易币种(T+0)  varchar(3)-->
                                    String cryType = tmpBkReader.readedXElement.getSingleText("cryType1");
                                    receiptData.cur = convertCurToATS(cryType);
                                }

                                int inRe = receiptHelper.insertIfNotExist(receiptData,true);
                                if (inRe == 1) {
                                    aLog="回单编号:"+ receiptData.istNbr + "写入数据库，影响行数：" + inRe;
                                    WriteBankLogLn(aLog);
                                    FGBiz.logTrace.info(this.getLogCode(), aLog);
                                } else if (inRe == 0) {
                                    aLog= "回单编号:"+receiptData.istNbr + "更新数据库，影响行数：" + inRe;
                                    WriteBankLogLn(aLog);
                                    FGBiz.logTrace.error(this.getLogCode(), aLog);
                                }
                            }
                        }else {
                            WriteBankLogLn(tmpStatusText);
                            FGBiz.logTrace.error(this.getLogCode(), tmpStatusText);
                        }
                    }else {
                        WriteBankLogLn(tmpSbMsg.toString());
                        FGBiz.logTrace.error(this.getLogCode(), tmpSbMsg.toString());
                    }
                }else {
                    WriteBankLogLn(tmpStrRet[1]);
                    FGBiz.logTrace.error(this.getLogCode(), tmpStrRet[1]);
                }
            }while (tmpReadedCount<tmpTotalCount);
        }catch (Exception ex){
            ex.printStackTrace();
            WriteBankLogLn(ex.getMessage());
            FGBiz.logTrace.error(this.getLogCode(), ex.getMessage());
        }
    }

    private String typeMapper(String billType) {
//        100000：存款回单；100001：取款回单；200000：转账回单；200001：缴税回单；300000：收费回单；400000定期回单；400001：活期回单-->
        if("100000".equals(billType)){
            return "1";
        }else if("100001".equals(billType)){
            return "2";
        }else if("200000".equals(billType)){
            return "3";
        }else if("200001".equals(billType)){
            return "4";
        }else if("300000".equals(billType)){
            return "5";
        }else if("400000".equals(billType)){
            return "6";
        }else if("400001".equals(billType)){
            return "7";
        }   else if("1".equals(billType)){
            return "100000";
        }else if("2".equals(billType)){
            return "100001";
        }else if("3".equals(billType)){
            return "200000";
        }else if("4".equals(billType)){
            return "200001";
        }else if("5".equals(billType)){
            return "300000";
        }else if("6".equals(billType)){
            return "400000";
        }else if("7".equals(billType)){
            return "400001";
        }
        return "";
    }

    public void pdfDownLoad(ReceiptDataHelper receiptHelper, ReceiptProConfig pConfig, ReqQryReceipt pReqReceipt, ArrayList<ReceiptData> list){
        String aLog="";
        List<String> deleteList = new ArrayList<String>();
        try {
            CITIC01Header downbankHeader = new CITIC01Header();
            downbankHeader.action = "DLEDCDTD";
            XmlTextWriter downxmlWriter = new XmlTextWriter();//发银行报文的XML对象

            //写入通用的头部节点
            writeCommonHeader(downxmlWriter, downbankHeader);

            downxmlWriter.writeElementString("bankId", "302");
            boolean isToday = DateHelper.compareDay(list.get(0).getBusDate(),new Date())==0;
            Date qryDate = list.get(0).getBusDate();
            downxmlWriter.writeElementString("isCurrDay",isToday?"1":"2" );//是否为T+0 日varchar (1)， 1：是；2：否
            downxmlWriter.writeElementString("accNo", list.get(0).ownAct);
            downxmlWriter.writeStartElementByAttr("list", "<list name=\"userDataList\">");
            for(ReceiptData receiptData:list) {
                downxmlWriter.writeStartElement("row");
                downxmlWriter.writeElementString("brSeqNo", receiptData.istNbr);
                //<!--回单类型varchar (6)，100000：存款回单；100001：取款回单；200000：转账回单；200001：缴税回单；300000：收费回单；400000定期回单；400001：活期回单-->
                downxmlWriter.writeElementString("billType",typeMapper(receiptData.receiptType));
                downxmlWriter.writeEndElement();
            }
            downxmlWriter.writeEndDocument();
            FGBiz.logTrace.info(this.getLogCode(),"发送银行的报文"+ downxmlWriter.toXmlString());
            String[] tmpStrRet = sendToBank(downxmlWriter.toXmlString());
            FGBiz.logTrace.info(this.getLogCode(), "银行返回的报文"+ FieldHiddenUtil.wordHiddle(tmpStrRet[1],new String[]{"DownloadFileContent"}));

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg1 = new StringBuilder();
                XmlTextReader downtmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg1);
                if (downtmpBkReader != null) {
                    String tmpStatus1 = downtmpBkReader.getFirstText("/stream/status");
                    String tmpStatusText1 = downtmpBkReader.getFirstText("/stream/statusText");
                    if (tmpStatus1 != null && tmpStatus1.equals("AAAAAAA")) {
                        String filecontent = downtmpBkReader.getFirstText("/stream/fileConTent");//文件内容
                        String fileName = downtmpBkReader.getFirstText("/stream/fileName");//名称
                        String tmpMainDir = pConfig.getSaveSubDir(pReqReceipt.reqHeader, list.get(0).getBusDate()) +
                                File.separator + "tmpMainDir" + File.separator + pReqReceipt.actNum + File.separator +list.get(0).busDate;
                        FileHelper.mkdir(tmpMainDir);
                        String localZipPath = tmpMainDir + File.separator + fileName;
                        String localUnzipDirPath = tmpMainDir + File.separator + fileName.substring(0, fileName.indexOf("."));
                        byte[] bytesFileContent = new BASE64Decoder().decodeBuffer(filecontent);
                        FileHelper.writeBytesToFile(localZipPath, bytesFileContent);
                        deleteList.add(localZipPath);

                        WriteBankLogLn("开始解压文件" + fileName + "至临时文件夹" + localUnzipDirPath);
                        ZipHelper.unZipFiles(localZipPath, localUnzipDirPath);
                        deleteList.add(localUnzipDirPath);

                        while (downtmpBkReader.read("/stream/list/row")) {
                            //回单编号
                            String billNo = downtmpBkReader.readedXElement.getSingleText("brseqNo");
                            ReceiptData receiptData = receiptHelper.loadFromDbByIstNbr(pReqReceipt.actNum, billNo);
                            //回单PDF文件名
                            String pdfname = downtmpBkReader.readedXElement.getSingleText("pdfName");
                            //本地备份文件
                            String localDirRelative = pConfig.getRelativeSaveDir(reqHeader, qryDate) + File.separator + pReqReceipt.actNum;
                            localDirRelative += File.separator + Format.Date10Format.format(qryDate);

                            String localFileRelative = localDirRelative + File.separator + StringHelper.trimStartFileSp(pdfname);
                            localFileRelative = StringHelper.replaceFileSp(localFileRelative);

                            String localFileReal = pConfig.localSaveMainDir + File.separator + localFileRelative;
                            String localtmpFilereal = localUnzipDirPath +File.separator+pdfname;
                            if(FileHelper.existFile(localtmpFilereal)){
                                FileHelper.copyFile(localtmpFilereal,localFileReal);
                            }
                            //下载回单文件
                            if (FileHelper.existFile(localFileReal)) {
                                int rowAff = receiptHelper.updateDownState(pReqReceipt.actNum, receiptData.istNbr, localFileRelative, pdfname, "2");
                                aLog = "回单编号" + receiptData.istNbr + "，文件" + pdfname + "下载成功，更新影响行数：" + rowAff;
                                aLog = aLog + "\r\n文件保存地址：" + localFileReal;
                                WriteBankLogLn(aLog);
                                FGBiz.logTrace.info(this.getLogCode(), aLog);
                            } else {
                                aLog = "回单编号" + receiptData.istNbr + "，文件" + pdfname + "下载失败";
                                WriteBankLogLn(aLog);
                                FGBiz.logTrace.error(this.getLogCode(), aLog);
                            }
                        }
                    }else {
                        WriteBankLogLn(tmpStatusText1);
                        FGBiz.logTrace.error(this.getLogCode(),tmpStatusText1);

                    }
                }else {
                    WriteBankLogLn(tmpSbMsg1.toString());
                    FGBiz.logTrace.error(this.getLogCode(),tmpSbMsg1.toString());
                }
            }else {
                WriteBankLogLn(tmpStrRet[1]);
                FGBiz.logTrace.error(this.getLogCode(),tmpStrRet[1]);
            }
        }catch (Exception ex){
            ex.printStackTrace();
            WriteBankLogLn(ex.getMessage());
            FGBiz.logTrace.error(this.getLogCode(), ex.getMessage());
        }finally {
            for(String filePath:deleteList) {
                boolean deleteflag = FileHelper.deleteRecursive(filePath);
                WriteBankLogLn("删除文件:" + filePath + (deleteflag ? " 成功" : " 失败"));
            }
        }
    }
}
